﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dunnice.BlogIndex.Entity;
using System.Threading;
using System.Text.RegularExpressions;
namespace Dunnice.BlogIndex.BLL.Adapter
{
    /// <summary>
    /// 博客园博客下载工具.
    /// </summary>
    public class CnBlogParser : IBlogParser
    {
        string _baseUrl = string.Format("http://www.cnblogs.com");

        /// <summary>
        /// 下载指定的博客文章到指定目录.
        /// </summary>
        /// <param name="item"></param>
        /// <param name="targetDirectory"></param>
        public string ParseArticleContent(BlogArticleInfo item)
        {
            string pageText = HtmlPageDownloader.DownloadUrlPage(item.Url).Replace("'", "\"");

            Regex contentRegex = new Regex(@"<div\s*id=""cnblogs_post_body"">", RegexOptions.IgnoreCase);
            Match startIndexM = contentRegex.Match(pageText);

            if (startIndexM.Success)
            {
                string tagStartSymbol = "<div ";
                string tagEndSymbol = "</div>";

                string content = SearchTagContent(pageText, startIndexM.Index, tagStartSymbol, tagEndSymbol);

                return content;
            }

            return pageText;
        }

        /// <summary>
        /// 罗列所有的文章目录.
        /// </summary>
        /// <param name="authorName"></param>
        /// <param name="callback"></param>
        public List<BlogArticleInfo> GetArticleItems(string authorName)
        {
            List<BlogArticleInfo> lstRes = new List<BlogArticleInfo>();

            for (int i = 1; ; i++)
            {
                string pageUrl = string.Format("{0}/{2}/default.html?page={1}&OnlyTitle=1", _baseUrl, i, authorName);

                string pageText = HtmlPageDownloader.DownloadUrlPage(pageUrl).Replace("'", "\"");

                if (pageText == null)
                {
                    break;
                }
                else
                {
                    List<BlogArticleInfo> lstPageItem = ParseChildPageInfo(pageUrl, pageText, authorName);

                    if (lstPageItem.Count == 0)
                    {
                        break;
                    }
                    lstRes.AddRange(lstPageItem);
                }
            }

            return lstRes;
        }

        /// <summary>
        /// 解析页面信息, 获取改页面的所有文章列表.
        /// </summary>
        /// <param name="pageUrl"></param>
        /// <param name="pageContent"></param>
        /// <param name="cbInfo"></param>
        /// <param name="asyncObj"></param>
        private List<BlogArticleInfo> ParseChildPageInfo(string pageUrl, string pageContent, string authorName)
        {
            List<BlogArticleInfo> lstRes = new List<BlogArticleInfo>();

            if (string.IsNullOrEmpty(pageContent))
            {
                pageContent = HtmlPageDownloader.DownloadUrlPage(pageUrl).Replace("'", "\"");
            }

            // 匹配文章URL:url
            // 文章名称:name 
            Regex titleUrlRegex = new Regex(@"class\s*=\s*""postTitle""[.\s""=\w<>]*?href\s*=\s*""(?<url>.*)""\s*>\s*(?<name>.*)\s*</a>", RegexOptions.IgnoreCase);

            // 匹配发布时间.
            Regex dateTimeRegex = new Regex(@"\s*(?<date>\d{4}-\d{2}-\d{2}\s*\d{2}:\d{2})\s*by|posted\s*@\s*(?<date>\d{4}-\d{2}-\d{2}\s*\d{2}:\d{2})\s*", RegexOptions.IgnoreCase);


            // 从URL中匹配页面名称.
            Regex pageNameRegex = new Regex(@"/(?<htmlname>[\w\s]*?\.html)$");

            // 匹配每一个文章的标题简介.
            Regex postRegex = new Regex(@"<div\s*class=""post""", RegexOptions.IgnoreCase);

            Match titleMatch = titleUrlRegex.Match(pageContent);

            while (titleMatch.Success)
            {
                //string tagStartSymbol = "<div ";
                //string tagEndSymbol = "</div>";

                //string content = SearchTagContent(pageContent, postMatch.Index, tagStartSymbol, tagEndSymbol);

                //Match m = titleUrlRegex.Match(content);

                //if (m.Success)
                //{
                //http://www.cnblogs.com/jv9/archive/2011/09/02/2163259.html
                string url = titleMatch.Groups["url"].Value;
                string name = titleMatch.Groups["name"].Value;
                string date = string.Empty;
                string htmlName = string.Empty;

                Match pageNameM = pageNameRegex.Match(url);
                if (pageNameM.Success)
                {
                    htmlName = pageNameM.Groups["htmlname"].Value;
                }

                Match dateM = dateTimeRegex.Match(pageContent, titleMatch.Index);
                if (dateM.Success)
                {
                    date = dateM.Groups["date"].Value;
                }

                BlogArticleInfo item = new BlogArticleInfo()
                {
                    Title = name,
                    DateString = date,
                    HtmlPageName = htmlName,
                    Url = url
                };

                lstRes.Add(item);
                //}

                titleMatch = titleMatch.NextMatch();
            }

            return lstRes;
        }
         
        /// <summary>
        /// 搜索Tag的内容.
        /// </summary>
        /// <param name="pageText"></param>
        /// <param name="startIndex"></param>
        /// <param name="tagStartSymbol"></param>
        /// <param name="tagEndSymbol"></param>
        /// <returns></returns>
        private static string SearchTagContent(string pageText, int startIndex, string tagStartSymbol, string tagEndSymbol)
        {
            int divCount = 0;
            int endIndex = startIndex + tagStartSymbol.Length;

            for (; endIndex < pageText.Length - tagEndSymbol.Length; endIndex++)
            {
                string subStr4 = pageText.Substring(endIndex, tagStartSymbol.Length).ToUpper();
                string subStr6 = pageText.Substring(endIndex, tagEndSymbol.Length).ToUpper();

                if (subStr4 == tagStartSymbol.ToUpper())
                {
                    divCount++;
                }
                else if (subStr6 == tagEndSymbol.ToUpper())
                {
                    divCount--;
                    if (divCount == 0)
                        break;
                }
            }

            string content = pageText.Substring(startIndex, endIndex + tagEndSymbol.Length - startIndex);

            return content;
        } 
    }
}
